package tema10.persistence;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import tema10.model.Contacto;

public class ContactoDAOPoolImplementation implements ContactoDAO {
    
    private static ContactoDAOPoolImplementation persistenceManager = null;
    private DataSource pool;
    private static final Logger logger = Logger.getLogger(ContactoDAOPoolImplementation.class.getName());
    
    private ContactoDAOPoolImplementation() {
    }

    public static ContactoDAOPoolImplementation getContactoDAOPoolImplementation() {
        if(persistenceManager == null)
            persistenceManager = new ContactoDAOPoolImplementation();

        return persistenceManager;
    }

    @Override
    public boolean createContacto(Contacto contacto) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return false;
        }
        boolean isExecutedOK = jDBCContactoDAO.createContacto(contacto);
        releaseQueryResources(jDBCContactoDAO);
        return isExecutedOK;
    }

    @Override
    public Contacto readContacto(String id) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return null;
        }
        Contacto contacto = jDBCContactoDAO.readContacto(id);
        releaseQueryResources(jDBCContactoDAO);
        return contacto;
    }
    
    @Override
    public Contacto readContacto(String nombre, String apellidos) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return null;
        }
        Contacto contacto = jDBCContactoDAO.readContacto(nombre,apellidos);
        releaseQueryResources(jDBCContactoDAO);
        return contacto;
    }

    @Override
    public boolean updateContacto(String id, Contacto contacto) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return false;
        }
        boolean isExecutedOK = jDBCContactoDAO.updateContacto(id, contacto);
        releaseQueryResources(jDBCContactoDAO);
        return isExecutedOK;
    }

    @Override
    public boolean deleteContacto(String id) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return false;
        }
        boolean isExecutedOK = jDBCContactoDAO.deleteContacto(id);
        releaseQueryResources(jDBCContactoDAO);
        return isExecutedOK;
    }

    @Override
    public String searchIDContacto(String nombre, String apellidos) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return null;
        }
        String id = jDBCContactoDAO.searchIDContacto(nombre, apellidos);
        releaseQueryResources(jDBCContactoDAO);
        return id;
    }
    
    //Cargamos el pool definido al DataSource pool
    @Override
    public boolean setUp(String url, String driver, String user, String password) {
        Context env = null;
        try {
            env = (Context) new InitialContext().lookup("java:comp/env");
            pool = (DataSource) env.lookup("jdbc/ejemplolpicontactos");
            if(pool == null){
                logger.log(Level.SEVERE, "No se encontro el DataSource");
                return false;
            }
        } catch (NamingException ex) {
            logger.log(Level.SEVERE, "No se pudo abrir la conexión contra base de datos", ex);
            return false;
        }
        return true;        
    }

    //Realmente no hay nada que desconectar a este nivel
    @Override
    public boolean disconnect() {
        return true;
    }
    
    //Las consultas individuales se hace creando un ContactoDAOJDBCImplementation
    private ContactoDAO prepareForExecutingQuery() {
        ContactoDAOJDBCImplementation jDBCpersistenceManager = new ContactoDAOJDBCImplementation ();
        Connection connection;
        try {
            connection = pool.getConnection();
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "No se pudo abrir la conexion contra la base de datos", ex);
            return null;
        }
        jDBCpersistenceManager.setConnection(connection);
        return jDBCpersistenceManager;
    }

    private void releaseQueryResources( ContactoDAO  contactoDAO) {
        contactoDAO.disconnect();
    }

    @Override
    public ArrayList listContactos(String nombre, String apellidos, String telefono, int dia, int mes, int anho) {
        ContactoDAO jDBCContactoDAO = prepareForExecutingQuery();
        if(jDBCContactoDAO == null){
            return (new ArrayList());
        }
        ArrayList<Contacto> listado = jDBCContactoDAO.listContactos(nombre, apellidos, telefono, dia, mes, anho);
        releaseQueryResources(jDBCContactoDAO);
        return listado;
    }

}
